package maquina.gestor.flujo;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import maquina.interfaz.io.Entrada;
import maquina.interfaz.io.Entrada.TipoEntrada;
import maquina.interfaz.usuario.InterfazUsuario;
import maquina.modelol.elector.Candidato;
import maquina.modelol.elector.Categoria;
import maquina.modelol.elector.LogicaVotacion;
import maquina.modelol.elector.Voto;

public class GestorIO {

	private InterfazUsuario interfazUsuario;

	private LogicaVotacion logicaVotacion;

	private GestorTarjeta gestorTarjeta;

	private int categoriaActual = 0;

	private int seleccionActual = -1;

	public GestorIO(LogicaVotacion logicaVotacion,
			InterfazUsuario interfazUsuario,
			int port) {

		this.logicaVotacion = logicaVotacion;

		this.interfazUsuario = interfazUsuario;

		try {

			this.gestorTarjeta = new GestorTarjeta(this, port);

		} catch (RemoteException e) {

			interfazUsuario.presentarFallaLector();

			System.out.println("Falla conexion lector de tarjeta");
		}

		List<List<Candidato>> list = new ArrayList<List<Candidato>>();

		List<Categoria> categorias = logicaVotacion.getCategorias();

		int i = 0;

		for (Categoria categoria : categorias) {

			list.add(categoria.getCandidatos());

			i++;
		}

		interfazUsuario.inicCandidatos(list);

		interfazUsuario.presentarEsperaTarjeta();

		gestorTarjeta.ping();
	}

	public void gestionarEntrada(Entrada entrada) {

		if ((entrada.getTipo() != TipoEntrada.CONTRASTE) && (entrada.getTipo() != TipoEntrada.NOCONTRASTE)) {

			if (entrada.getTipo() == TipoEntrada.SELECCION) {

				if (!logicaVotacion.seleccionCompleta()) {

					gestionarSeleccion(entrada.getPos());
				}
			} else {

				if (seleccionActual != -1) {

					if (!logicaVotacion.seleccionCompleta()) {

						gestionarSeleccionConfirmada();
					} else {

						gestionarCierreVotacion();
					}
				}
			}
		} else {
			
			    gestionarContraste(entrada);
		       }

	}

	private void gestionarContraste(Entrada entrada) {
		
		List<List<Candidato>> list = new ArrayList<List<Candidato>>();

		List<Categoria> categorias = logicaVotacion.getCategorias();

		int i = 0;

		for (Categoria categoria : categorias) {

			list.add(categoria.getCandidatos());

			i++;
		}
        
		if (entrada.getTipo() == TipoEntrada.CONTRASTE){
		   
			interfazUsuario.presentarContraste(list);
		}else{
			
			  interfazUsuario.presentarNoContraste(list);
		     }
	}


	private void gestionarSeleccion(int pos) {

		Categoria categoria = logicaVotacion.getCategorias().get(
				categoriaActual);

		if (!logicaVotacion.isCategoriaCompleta(categoria)) {

			if (seleccionActual != pos) {

				if (seleccionActual == -1) {

					interfazUsuario.seleccionar(pos);

					seleccionActual = pos;
				}
			} else {

				interfazUsuario.desSeleccionar(pos);

				seleccionActual = -1;
			}
		}
	}

	private void gestionarSeleccionConfirmada() {

		Categoria categoria = logicaVotacion.getCategorias().get(
				categoriaActual);

		logicaVotacion.seleccionar(categoria, categoria.getCandidatos().get(
				seleccionActual - 1));

		if (logicaVotacion.isCategoriaCompleta(categoria)) {

			if (logicaVotacion.seleccionCompleta()) {

				gestionarCierreVotacion();

			} else {

				interfazUsuario.presentarCategoriaSiguiente();

				categoriaActual++;
			}
		} else {

			interfazUsuario.desSeleccionar(seleccionActual);
		}

		seleccionActual = -1;
	}

	public void ingresoNuevaTarjeta() {

		interfazUsuario.iniciarNuevaVotacion();
	}

	public void gestionarCierreVotacion() {

		categoriaActual = 0;

		seleccionActual = -1;

		interfazUsuario.presentarEsperaTarjeta();

		List<String> list = new ArrayList<String>();

		Map<Categoria, Voto> votacion = logicaVotacion.getVotacion();
		
		for (Categoria categoria : votacion.keySet()) {

			list.add(String.valueOf(votacion.get(categoria)));			
		}
		
		gestorTarjeta.escribirTarjeta(list);

		// --------------------------------------------------------------------
		System.out.println("Ya se escribio tarjeta: proximo a hacer ping");

		try {
			Thread.sleep(5000);

		} catch (InterruptedException e) {}
		// --------------------------------------------------------------------

		gestorTarjeta.ping();

	}

	public void gestionarFallaLector() {

		interfazUsuario.presentarFallaLector();
	}
}
